﻿@inherits TestComponentBase

<Fixture Setup="Setup1" Test="Test1" Tests="new Action[] { Test1_1 }">
    <ComponentUnderTest>
        <SimpleWithDeps />
    </ComponentUnderTest>
    <Fragment>
        <Simple1 />
    </Fragment>
</Fixture>
@code {
    private ITestOutputHelper _output;

    public CorrectImplicitRazorTestContextAvailable(ITestOutputHelper output)
    {
        _output = output;
        Services.AddXunitLogger(_output);
    }

    class Dep1 : ITestDep { public string Name => nameof(Dep1); }
    ITestDep dep1Expected = new Dep1();

    void Setup1()
    {
        Services.AddSingleton<ITestDep>(dep1Expected);
        Services.AddXunitLogger(_output);
    }

    void Test1()
    {
        this.
        GetComponentUnderTest<SimpleWithDeps>().Find("p").TextContent.ShouldBe(dep1Expected.Name);
        GetFragment<Simple1>().ShouldNotBeNull();
    }

    void Test1_1()
    {
        GetComponentUnderTest<SimpleWithDeps>().Find("p").TextContent.ShouldBe(dep1Expected.Name);
        GetFragment<Simple1>().ShouldNotBeNull();
    }

    Task TestAsync1()
    {
        GetComponentUnderTest<SimpleWithDeps>().Find("p").TextContent.ShouldBe(dep1Expected.Name);
        GetFragment<Simple1>().ShouldNotBeNull();
        return Task.CompletedTask;
    }
}

<Fixture Description="TADA" Setup="Setup2" Test="Test2" Tests="new Action[] { Test2_1 }">
    <ComponentUnderTest>
        <Wrapper />
    </ComponentUnderTest>
    <Fragment>
        <SimpleWithDeps />
    </Fragment>
</Fixture>
@code {
    class Dep2 : ITestDep { public string Name => nameof(Dep2); }
    ITestDep dep2Expected = new Dep1();

    void Setup2()
    {
        Services.AddSingleton<ITestDep>(dep2Expected);
    }

    void Test2()
    {
        GetComponentUnderTest<Wrapper>().ShouldNotBeNull();
        GetFragment<SimpleWithDeps>().Find("p").TextContent.ShouldBe(dep2Expected.Name);
    }

    void Test2_1()
    {
        GetComponentUnderTest<Wrapper>().ShouldNotBeNull();
        GetFragment<SimpleWithDeps>().Find("p").TextContent.ShouldBe(dep2Expected.Name);
    }
}

@code {
    [Fact(DisplayName = "When running c# only test in razor file, all razor test context specific methods throws")]
    public void MyTestMethod()
    {
        Should.Throw<InvalidOperationException>(() => GetComponentUnderTest())
            .Message.ShouldEndWith("is only available in Razor based tests.");

        Should.Throw<InvalidOperationException>(() => GetComponentUnderTest<IComponent>())
            .Message.ShouldEndWith("is only available in Razor based tests.");

        Should.Throw<InvalidOperationException>(() => GetFragment())
            .Message.ShouldEndWith("is only available in Razor based tests.");

        Should.Throw<InvalidOperationException>(() => GetFragment<IComponent>())
            .Message.ShouldEndWith("is only available in Razor based tests.");
    }
}

<SnapshotTest Description="Snapshot tests should have own context" Setup="() => Services.AddSingleton<ITestDep>(new Dep3())">
    <TestInput><SimpleWithDeps /></TestInput>
    <ExpectedOutput><p>@nameof(Dep3)</p></ExpectedOutput>
</SnapshotTest>

@code{
    class Dep3 : ITestDep { public string Name => nameof(Dep3); }
}